/******************************************************************************
 * 
 * Announce: CSharpKit, Basic algorithms, components and definitions.
 *           Copyright (C) ShenYongchen.
 *           All rights reserved.
 *   Author: 申永辰.郑州 (shenyczz@163.com)
 *  WebSite: http://github.com/shenyczz/CSharpKit
 *
 * THIS CODE IS LICENSED UNDER THE MIT LICENSE (MIT).
 * THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 
 * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
 * IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
 * PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
 * 
******************************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;

namespace CSharpKit.Convertions
{
    public sealed class IntPtrConverter
    {
        IntPtrConverter() { }
        public static readonly IntPtrConverter Instance = new IntPtrConverter();

        private const int BUFFER_SIZE = 1024;



        public IntPtr FromBytes(IEnumerable<byte> bytes)
        {
            var ptr = default(IntPtr);

            try
            {
                var hObject = GCHandle.Alloc(bytes.ToArray(), GCHandleType.Pinned);
                ptr = hObject.AddrOfPinnedObject();
                if (hObject.IsAllocated) hObject.Free();
            }
            catch (Exception)
            {
                // throw;
            }

            return ptr;
        }

        // 
        public IEnumerable<byte> ToBytes(IntPtr p, int len = 0)
        {
            var result = default(IEnumerable<byte>);

            try
            {
                var actual_len = len == 0 ? BUFFER_SIZE : len;
                var uctemp = new byte[actual_len];
                Marshal.Copy(p, uctemp, 0, actual_len);

                result = uctemp;
            }
            catch (Exception)
            {
                result = null;
            }

            return result;
        }


        public string ToString(IntPtr p, int len = 0)
        {
            string str_value = "";

            try
            {
                int actual_len = len == 0 ? BUFFER_SIZE : len;
                byte[] uc_temp = new byte[actual_len];
                Marshal.Copy(p, uc_temp, 0, actual_len);
                str_value = BytesConverter.Instance.ToString(uc_temp);
            }
            catch (Exception)
            {
                // str_value = "";
                // Marshal.PtrToStringAnsi()
                // Marshal.PtrToStructure<Target>()
                // Marshal.StructureToPtr<T>()
            }

            return str_value;
        }



        //}}@@@
    }


}

